
#include "BuildinMath.h"


#ifndef UTILS_ORTHOGRAPHICCAMERA
#define UTILS_ORTHOGRAPHICCAMERA

enum class CameraTransform2D {
    MoveUp, MoveDown, MoveLeft, MoveRight, 
    RotateLeft, RotateRight
};

class OrthographicCamera {
public:
    Matrix4f projection = Matrix4f(1.f);
    Matrix4f view = Matrix4f(1.f);
    Matrix4f view_projection = Matrix4f(1.f);

    Vector3f position = ZeroVector3f;
    float rotation = 0.0f;

    float moveSpeed = 100.0f;
    float rotationSpeed = 100.0f;

    void configure(
        const float left, const float right,
        const float bottom, const float top,
        const float near, const float far
    ) {
        projection = Ortho(left, right, bottom, top, near, far);
        recalculate();
    }

    void keyboardTransform(const CameraTransform2D transform, const float delta) {
        switch (transform) {
            default: break;
            case CameraTransform2D::MoveUp: position.y += delta * moveSpeed; break;
            case CameraTransform2D::MoveDown: position.y -= delta * moveSpeed; break;
            case CameraTransform2D::MoveLeft: position.x -= delta * moveSpeed; break;
            case CameraTransform2D::MoveRight: position.x += delta * moveSpeed; break;
            case CameraTransform2D::RotateLeft: rotation += delta * rotationSpeed; break;
            case CameraTransform2D::RotateRight: rotation -= delta * rotationSpeed; break;
        }
        recalculate();
    }

private:
    void recalculate() {
        // Matrix4f transform = glm::translate(Matrix4f(1.0f), position) * glm::rotate(Matrix4f(1.0f), glm::radians(rotation), Vector3f(0.0f, 0.0f, 1.0f));
        // view = glm::inverse(transform);
        view = glm::lookAt(position, position + Vector3f(0.0f, 0.0f, -1.0f), Vector3f(0.0f, 1.0f, 0.0f));
        view_projection = projection * view;
    }
};

#endif // UTILS_ORTHOGRAPHICCAMERA
